import { initVueI18n } from '@dcloudio/uni-i18n';
import i18nMessages from '@/locale';
import { useAuthStore } from '@/store/auth';
import { GET_BASE_CONFIG } from './env';
import { addRequestInterceptor, addResponseInterceptor } from './interceptor';
import { decryptData, encryptData } from './security';
import { isWechat } from '@/utils/platform';

type RequestMethod = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';

const { t } = initVueI18n(i18nMessages as any);

function mergeUrl(url: string) {
  return GET_BASE_CONFIG().BASE_URL + url;
}

addRequestInterceptor((args) => {
  args.header = {
    ...args.header,
    'x-language': uni.getStorageSync('language') || 'zh',
    'x-channel': isWechat() ? 'miniapp' : 'h5'
  };
});

addRequestInterceptor((args) => {
  const token = uni.getStorageSync('token');
  if (token) {
    args.header = {
      ...args.header,
      Authorization: token
    };
  }
});

addResponseInterceptor((args) => {
  if (args.data && args.data.resCode === 0 && args.data.resData) {
    args.data = decryptData(args.data.resData);
    const token = uni.getStorageSync('token');
    console.log(args.data);
    if (parseInt(args.data.code) === 61 && token !== '') {
      uni.removeStorageSync('token');
    }
    if (args.data.code !== 0 && token !== '') {
      if (args.data.message.length > 5) {
        return uni.showModal({
          content: args.data.message,
          showCancel: false,
          confirmText: t('LCKey_confirm')
        });
      } else {
        return uni.showToast({
          title: args.data.message,
          icon: 'error'
        });
      }
    }
    if (args.data.code == 61) {
      const authStore = useAuthStore();
      authStore.logout();
    }
  }
});

const taskQueue: Map<string, Promise<any>> = new Map();

type RequestOptions = {
  url: string;
  method: RequestMethod;
  data?: any;
  loadingText?: string;
};

/**
 * 发起基础请求的函数。
 */
async function baseRequest<T = any>(options: RequestOptions): Promise<T> {
  const data = await encryptData(options.data);
  const requestTask = new Promise<T>((resolve, reject) => {
    // 在请求开始时显示加载提示
    uni.showLoading({ title: options.loadingText, mask: true });
    uni.request({
      // 合并基础URL和传入的URL
      url: mergeUrl(options.url),
      method: options.method,
      // 对请求数据进行加密
      data,
      success(res) {
        // 请求成功时，解析并返回结果
        resolve(res.data as T);
      },
      fail(err) {
        if (err.errMsg === 'request:fail ') {
          uni.showToast({
            title: 'network error',
            icon: 'error'
          });
        }
        // 请求失败时，拒绝并返回错误信息
        reject(err);
      },
      complete() {
        // 请求完成后，从任务队列中移除
        taskQueue.delete(options.url);

        // 如果任务队列中没有任务，隐藏加载提示
        if (taskQueue.size === 0) {
          uni.hideLoading();
          request.options.loadingText = '加载中...';
        }
      }
    });
  });
  // 将请求任务添加到任务队列中
  taskQueue.set(options.url, requestTask);
  return requestTask;
}

export const request = {
  options: {
    loadingText: '加载中...'
  },
  get(url: string) {
    return baseRequest({
      url,
      method: 'GET',
      ...this.options
    });
  },
  post<T = any>(url: string, data: any = {}) {
    return baseRequest<T>({
      url,
      method: 'POST',
      data,
      ...this.options
    });
  }
};

export type Response<D = any> = {
  code: number;
  message: string;
  data: D;
};

export type ListResponse<D> = Response<{
  list: D[];
}>;

export type Pagination<D> = {
  total: number;
  per_page: number;
  current_page: number;
  last_page: number;
  data: D[];
};

export type ListResponseWithPagination<D> = Response<{
  list: Pagination<D>;
}>;

export type DetailsResponse<D = any> = Response<{
  detail: D;
}>;
